﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls.Primitives;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Effects;
using System.Windows.Media;
using System.Windows;
using CarAppClient.Helpers;
using System.Windows.Threading;
using System.Windows.Media.Animation;
using CarAppClient.Controls.TransitionsUserControls;

namespace CarAppClient.Controls.Base
{
    /// <summary>
    /// 基础窗体，已实现窗体拖动，双击全屏、还原、最大化、最小化、关闭功能、自动关闭等功能
    /// </summary>
    public class BaseWindow : Window
    {
        #region 初始化窗口

        static BaseWindow()
        {
            // .NET 4.5 以后使用此方法作为设置默认样式， x:key =BaseWindowStyle
            StyleProperty.OverrideMetadata(typeof(BaseWindow), new FrameworkPropertyMetadata(ResourceHelper.GetResourceKey<Style>("BaseWindowStyle")));
            //DefaultStyleKeyProperty.OverrideMetadata(typeof(BaseWindow), new FrameworkPropertyMetadata(typeof(BaseWindow)));
        }

        public BaseWindow()
        {
            this.Loaded += BaseWindow_Loaded;
        }
        private void BaseWindow_Loaded(object sender, RoutedEventArgs e)
        {
            switch (this.WindowState)
            {
                case WindowState.Maximized:
                    this.WindowState = WindowState.Normal;
                    this.SetWindowMaximized();
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 设置窗口最大化
        /// </summary>
        private void SetWindowMaximized()
        {
            if (VisualTreeHelper.GetChildrenCount(this) > 0)
            {
                //最大化窗体前保留窗体的原始大小与位置
                this.restore_window_width = this.Width;
                this.restore_window_height = this.Height;
                this.resotre_left = this.Left;
                this.resotre_top = this.Top;

                Grid a = (Grid)VisualTreeHelper.GetChild(this, 0);
                //设置Grid的Margin为0，用于去除窗体阴影
                a.Margin = new Thickness(0, 0, 0, 0);
                Border b = (Border)VisualTreeHelper.GetChild(a, 0);
                //隐藏阴影
                b.Visibility = Visibility.Collapsed;
                this.Left = 0;
                this.Top = 0;

                Rect rc = SystemParameters.WorkArea;//获取工作区大小
                this.Width = rc.Width;
                this.Height = rc.Height;

                // 设置后widnows底部任务栏会出隐藏
                // this.Animation(this.Width, this.Height, rc.Width, rc.Height);

                this.mIsMaximized = true;
                if (Btn_Maximized != null)
                {
                    Btn_Maximized.Visibility = Visibility.Hidden;
                }
                if (Btn_Restore != null)
                {
                    this.Btn_Restore.Visibility = Visibility.Visible;
                }
            }
        }

        Storyboard storyboard = new Storyboard();
        private void Animation(double oldWidth, double oldHeight, double newWidth, double newHeight)
        {
            DoubleAnimation widthAnimation = new DoubleAnimation(oldWidth, newWidth, new Duration(TimeSpan.FromMilliseconds(500)));
            Storyboard.SetTarget(widthAnimation, this);
            Storyboard.SetTargetProperty(widthAnimation, new PropertyPath("(Window.Width)"));
            storyboard.Children.Add(widthAnimation);

            DoubleAnimation heightAnimation = new DoubleAnimation(oldWidth, newWidth, new Duration(TimeSpan.FromMilliseconds(500)));
            Storyboard.SetTarget(heightAnimation, this);
            Storyboard.SetTargetProperty(heightAnimation, new PropertyPath("(Window.Height)"));
            storyboard.Children.Add(heightAnimation);

            storyboard.Begin();
        }

        /// <summary>
        /// 还原窗体大小
        /// </summary>
        private void SetWindowSizeRestore()
        {
            if (VisualTreeHelper.GetChildrenCount(this) > 0)
            {
                Grid a = (Grid)VisualTreeHelper.GetChild(this, 0);
                //设置Grid的Margin，用于显示窗体阴影
                a.Margin = new Thickness(20, 20, 20, 20);
                Border b = (Border)VisualTreeHelper.GetChild(a, 0);
                //显示阴影
                b.Visibility = Visibility.Visible;
                this.Left = this.resotre_left;
                this.Top = this.resotre_top;
                this.Width = this.restore_window_width;
                this.Height = this.restore_window_height;

                this.mIsMaximized = false;
                if (this.Btn_Restore != null)
                {
                    this.Btn_Restore.Visibility = Visibility.Hidden;
                }
                if (this.Btn_Maximized != null)
                {
                    this.Btn_Maximized.Visibility = Visibility.Visible;
                }
            }
        }

        #endregion

        #region 最小化按钮
        /// <summary>
        /// 是否显示最小化按钮
        /// </summary>
        public bool ShowMinimizeBox
        {
            get { return (bool)GetValue(ShowMinimizeBoxProperty); }
            set { SetValue(ShowMinimizeBoxProperty, value); }
        }
        public static readonly DependencyProperty ShowMinimizeBoxProperty = DependencyProperty.Register("ShowMinimizeBox", typeof(bool), typeof(BaseWindow), new PropertyMetadata(false));

        #endregion

        #region 最大化按钮

        /// <summary>
        /// 是否显示最大化按钮
        /// </summary>
        public bool ShowMaximizeBox
        {
            get { return (bool)GetValue(ShowMaximizeBoxProperty); }
            set { SetValue(ShowMaximizeBoxProperty, value); }
        }
        public static readonly DependencyProperty ShowMaximizeBoxProperty = DependencyProperty.Register("ShowMaximizeBox", typeof(bool), typeof(BaseWindow), new PropertyMetadata(false));


        #endregion

        #region 关闭按钮

        /// <summary>
        /// 是否显示关闭按钮
        /// </summary>
        public bool ShowCloseBox
        {
            get { return (bool)GetValue(ShowCloseBoxProperty); }
            set { SetValue(ShowCloseBoxProperty, value); }
        }
        public static readonly DependencyProperty ShowCloseBoxProperty = DependencyProperty.Register("ShowCloseBox", typeof(bool), typeof(BaseWindow), new PropertyMetadata(true));


        #endregion

        #region 右上角菜单
        public string IconShowMenu
        {
            get { return (string)GetValue(IconShowMenuProperty); }
            set { SetValue(IconShowMenuProperty, value); }
        }
        public static readonly DependencyProperty IconShowMenuProperty = DependencyProperty.Register("IconShowMenu", typeof(string), typeof(BaseWindow));

        /// <summary>
        /// 是否显示菜单
        /// </summary>
        public bool ShowMenu
        {
            get { return (bool)GetValue(ShowMenuProperty); }
            set { SetValue(ShowMenuProperty, value); }
        }
        public static readonly DependencyProperty ShowMenuProperty = DependencyProperty.Register("ShowMenu", typeof(bool), typeof(BaseWindow), new PropertyMetadata(true));

        /// <summary>
        /// 是否显示其他扩展控件
        /// </summary>
        public bool ShowExtend
        {
            get { return (bool)GetValue(ShowExtendProperty); }
            set { SetValue(ShowExtendProperty, value); }
        }
        public static readonly DependencyProperty ShowExtendProperty = DependencyProperty.Register("ShowExtend", typeof(bool), typeof(BaseWindow), new PropertyMetadata(false));


        /// <summary>
        /// 是否显示菜单按钮
        /// </summary>
        public bool ShowMore
        {
            get { return (bool)GetValue(ShowMoreProperty); }
            set { SetValue(ShowMoreProperty, value); }
        }
        public static readonly DependencyProperty ShowMoreProperty = DependencyProperty.Register("ShowMore", typeof(bool), typeof(BaseWindow), new PropertyMetadata(false));

        #endregion

        #region 顶部标题栏

        /// <summary>
        /// 标题内容
        /// </summary>
        [Bindable(true)]
        public object HeaderContent
        {
            get { return (object)GetValue(HeaderContentProperty); }
            set { SetValue(HeaderContentProperty, value); }
        }
        public static readonly DependencyProperty HeaderContentProperty = DependencyProperty.Register("HeaderContent", typeof(object), typeof(BaseWindow));


        /// <summary>
        /// 是否显示头部标题栏
        /// </summary>
        public bool IsShowHeader
        {
            get { return (bool)GetValue(IsShowHeaderProperty); }
            set { SetValue(IsShowHeaderProperty, value); }
        }
        public static readonly DependencyProperty IsShowHeaderProperty = DependencyProperty.Register("IsShowHeader", typeof(bool), typeof(BaseWindow), new PropertyMetadata(false));

        /// <summary>
        /// 标题栏高度
        /// </summary>
        public double CaptionHeight
        {
            get { return (double)GetValue(CaptionHeightProperty); }
            set { SetValue(CaptionHeightProperty, value); }
        }
        public static readonly DependencyProperty CaptionHeightProperty = DependencyProperty.Register("CaptionHeight", typeof(double), typeof(BaseWindow), new PropertyMetadata(30d));

        /// <summary>
        /// 头部标题栏文字颜色
        /// </summary>
        [Bindable(true)]
        public Brush HeaderForeground
        {
            get { return (Brush)GetValue(HeaderForegroundProperty); }
            set { SetValue(HeaderForegroundProperty, value); }
        }
        public static readonly DependencyProperty HeaderForegroundProperty = DependencyProperty.Register("HeaderForeground", typeof(Brush), typeof(BaseWindow), new PropertyMetadata(Brushes.White));


        /// <summary>
        /// 头部标题栏背景色
        /// </summary>
        public Brush TitleBackground
        {
            get { return (Brush)GetValue(TitleBackgroundProperty); }
            set { SetValue(TitleBackgroundProperty, value); }
        }
        public static readonly DependencyProperty TitleBackgroundProperty = DependencyProperty.Register("TitleBackground", typeof(Brush), typeof(BaseWindow));

        #region 公示信息
        /// <summary>
        /// 公示信息
        /// </summary>
        public string NoticeDetail
        {
            get { return (string)GetValue(NoticeDetailProperty); }
            set { SetValue(NoticeDetailProperty, value); }
        }
        public static readonly DependencyProperty NoticeDetailProperty = DependencyProperty.Register("NoticeDetail", typeof(string), typeof(BaseWindow));

        #endregion

        #endregion

        #region 显示全局遮罩层
        /// <summary>
        /// 显示隐藏遮罩层
        /// </summary>
        public bool IsMaskVisible
        {
            get { return (bool)GetValue(IsMaskVisibleProperty); }
            set { SetValue(IsMaskVisibleProperty, value); }
        }
        public static readonly DependencyProperty IsMaskVisibleProperty = DependencyProperty.Register("IsMaskVisible", typeof(bool), typeof(BaseWindow));

        #endregion

        #region 窗体能否被拖动

        /// <summary>
        /// 窗体能否被拖动
        /// </summary>
        public bool CanMoveWindow
        {
            get { return (bool)GetValue(CanMoveWindowProperty); }
            set { SetValue(CanMoveWindowProperty, value); }
        }
        public static readonly DependencyProperty CanMoveWindowProperty = DependencyProperty.Register("CanMoveWindow", typeof(bool), typeof(BaseWindow), new PropertyMetadata(true));

        /// <summary>
        /// 拖动窗体事件重写
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            if (!this.CanMoveWindow) return;

            if (this.mIsMaximized) return;

            base.OnMouseLeftButtonDown(e);

            if (TitleBar != null)
            {
                // 获取鼠标相对标题栏位置  
                Point position = e.GetPosition(TitleBar);

                // 如果鼠标位置在标题栏内，允许拖动  
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    if (position.X >= 0 && position.X < TitleBar.ActualWidth && position.Y >= 0
                        && position.Y < TitleBar.ActualHeight)
                    {
                        this.DragMove();
                    }
                }
            }
        }

        #endregion

        #region 窗体相关控件声明

        /// <summary>
        /// 关闭按钮
        /// </summary>
        private Button? Btn_Close = null;

        /// <summary>
        /// 最小化按钮
        /// </summary>
        private Button? Btn_Minimized = null;

        /// <summary>
        /// 最大化按钮
        /// </summary>
        private Button? Btn_Maximized = null;

        /// <summary>
        /// 还原按钮
        /// </summary>
        private Button? Btn_Restore = null;

        /// <summary>
        /// 快捷菜单按钮
        /// </summary>
        private Button? Btn_More = null;

        /// <summary>
        /// 标题
        /// </summary>
        private Grid? TitleBar = null;

        /// <summary>
        /// 子菜单
        /// </summary>
        private Popup? Popup_Menu = null;

        /// <summary>
        /// 保存上一次窗体的宽度
        /// </summary>
        private double restore_window_width = 0;

        /// <summary>
        /// 保存上一次窗体的高度
        /// </summary>
        private double restore_window_height = 0;

        /// <summary>
        /// 保存上一次窗体距离屏幕左边位置
        /// </summary>
        private double resotre_left = 0;

        /// <summary>
        /// 保存上一次窗体距离屏幕顶部位置
        /// </summary>
        private double resotre_top = 0;

        /// <summary>
        /// 当前窗体是否处于最大化状态，用于窗体最大化与原大小间切换
        /// </summary>
        private bool mIsMaximized = false;

        /// <summary>
        /// 鼠标点击次数，用于判断鼠标双击
        /// </summary>
        private int mouseClickCount = 0;
        #endregion

        /// <summary>
        /// 动画类型
        /// </summary>
        [Bindable(true)]
        public AnimationTypeEnum AnimationTypeEnumType
        {
            get { return (AnimationTypeEnum)GetValue(AnimationTypeEnumTypeProperty); }
            set { SetValue(AnimationTypeEnumTypeProperty, value); }
        }
        public static readonly DependencyProperty AnimationTypeEnumTypeProperty = DependencyProperty.Register("AnimationTypeEnumType", typeof(AnimationTypeEnum), typeof(BaseWindow), new PropertyMetadata(AnimationTypeEnum.Default));


        #region 查找控件元素，绑定事件

        /// <summary>
        /// 我们会自定义模板来定义控件的外观，添加命令和路由事件来给控件添加行为，
        /// 那如何在模板中查找元素并关联事件处理程序或添加数据绑定表达式呢，
        /// WPF有一个专用的OnApplyTemplate()方法，在该方法中，可以使用GetTemplateChild或FindName来查找所需的元素
        /// </summary>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.Btn_Close = VisualHelper.FindVisualElement<Button>(this, "Btn_Close");
            this.Btn_Minimized = VisualHelper.FindVisualElement<Button>(this, "Btn_Minimized");
            this.Btn_Maximized = VisualHelper.FindVisualElement<Button>(this, "Btn_Maximized");
            this.Btn_Restore = VisualHelper.FindVisualElement<Button>(this, "Btn_Restore");
            this.TitleBar = VisualHelper.FindVisualElement<Grid>(this, "TitleBar");
            this.Btn_More = VisualHelper.FindVisualElement<Button>(this, "Btn_More");
            this.Popup_Menu = VisualHelper.FindVisualElement<Popup>(this, "Popup_Menu");

            if (this.Btn_Close != null)
            {
                this.Btn_Close.Click += (object sender, RoutedEventArgs e) =>
                {
                    this.Close();
                };
            }
            if (this.Btn_Minimized != null)
            {
                this.Btn_Minimized.Click += (object sender, RoutedEventArgs e) =>
                {
                    this.WindowState = WindowState.Minimized;
                };
            }


            if (this.Btn_Restore != null)
            {
                this.Btn_Restore.Click += (object sender, RoutedEventArgs e) =>
                {
                    SetWindowSizeRestore();
                };
            }

            if (this.Btn_Maximized != null)
            {
                this.Btn_Maximized.Click += (object sender, RoutedEventArgs e) =>
                {
                    SetWindowMaximized();
                };
            }

            if (this.Btn_More != null)
            {
                this.Btn_More.Click += (object sender, RoutedEventArgs e) =>
                {
                    if (this.Btn_More != null && this.Popup_Menu != null)
                    {
                        this.Popup_Menu.Child = this.MenuPanel;
                        this.Popup_Menu.IsOpen = true;
                    }
                };
            }

            if (this.TitleBar != null)
            {
                if (!this.ShowMaximizeBox && !this.ShowMinimizeBox && !this.ShowCloseBox && string.IsNullOrEmpty(this.Title.Trim()))
                {
                    this.TitleBar.Visibility = Visibility.Collapsed;
                }

                this.TitleBar.MouseLeftButtonDown += (object sender, MouseButtonEventArgs e) =>
                {
                    //不允许最大化的时候，双击标题栏自然也不允许将窗体最大化
                    if (!this.ShowMaximizeBox) return;

                    mouseClickCount += 1;
                    DispatcherTimer timer = new DispatcherTimer();
                    //设置鼠标左键点击间隔为0.3秒，超过0.3秒将mouseClickCount重置
                    timer.Interval = new TimeSpan(0, 0, 0, 0, 300);
                    timer.Tick += (s, e1) => { timer.IsEnabled = false; mouseClickCount = 0; };
                    timer.IsEnabled = true;
                    if (mouseClickCount % 2 == 0)
                    {
                        timer.IsEnabled = false;
                        mouseClickCount = 0;

                        //判断当前窗体状态，如果是最大化，则双击之后还原窗体大小，否则将窗体最大化
                        if (this.mIsMaximized)
                        {
                            this.SetWindowSizeRestore();
                        }
                        else
                        {
                            this.SetWindowMaximized();
                        }
                    }
                };
            }
        }


        #endregion

        public Effect HeaderEffect
        {
            get { return (Effect)GetValue(HeaderEffectProperty); }
            set { SetValue(HeaderEffectProperty, value); }
        }

        public static readonly DependencyProperty HeaderEffectProperty = DependencyProperty.Register("HeaderEffect", typeof(Effect), typeof(BaseWindow));

        /// <summary>
        /// Fill of mask cover. The default is #AA3E3E3E.
        /// </summary>
        public Brush MaskBrush
        {
            get { return (Brush)GetValue(MaskBrushProperty); }
            set { SetValue(MaskBrushProperty, value); }
        }
        public static readonly DependencyProperty MaskBrushProperty = DependencyProperty.Register("MaskBrush", typeof(Brush), typeof(BaseWindow));

        public string Network
        {
            get { return (string)GetValue(NetworkProperty); }
            set { SetValue(NetworkProperty, value); }
        }
        public static readonly DependencyProperty NetworkProperty = DependencyProperty.Register("Network", typeof(string), typeof(BaseWindow));

        /// <summary>
        /// 其他控件
        /// </summary>
        public UIElement ExtendControl
        {
            get { return (UIElement)GetValue(ExtendControlProperty); }
            set { SetValue(ExtendControlProperty, value); }
        }
        public static readonly DependencyProperty ExtendControlProperty = DependencyProperty.RegisterAttached("ExtendControl", typeof(UIElement), typeof(BaseWindow));

        /// <summary>
        /// 菜单栏面板
        /// </summary>
        public Panel MenuPanel
        {
            get { return (Panel)GetValue(MenuPanelProperty); }
            set { SetValue(MenuPanelProperty, value); }
        }
        public static readonly DependencyProperty MenuPanelProperty = DependencyProperty.Register("MenuPanel", typeof(Panel), typeof(BaseWindow));


        public event RoutedPropertyChangedEventHandler<object> ShowMoreClick
        {
            add
            {
                this.AddHandler(ShowMoreClickEvent, value);
            }
            remove
            {
                this.RemoveHandler(ShowMoreClickEvent, value);
            }
        }
        public static readonly RoutedEvent ShowMoreClickEvent = EventManager.RegisterRoutedEvent("ShowMoreClick", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<object>), typeof(BaseWindow));

        protected virtual void OnShowMoreClick(object oldValue, object newValue)
        {
            RoutedPropertyChangedEventArgs<object> arg = new RoutedPropertyChangedEventArgs<object>(oldValue, newValue, ShowMoreClickEvent);
            this.RaiseEvent(arg);
        }
    }
}
